/**
 * @Title: AuthInterceptor.java
 * @Package com.kaver.sso.interceptor
 * @author roc
 * @date Aug 11, 2021 2:05:18 PM
 * @version V1.0
 * @copyright kaver
 */
package com.kaver.sso.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.kaver.sso.config.PropertiesConfig;
import com.kaver.sso.helper.SsoUserHolder;
import com.kaver.sso.helper.UnAuth;
import com.kaver.sso.path.PathMatcher;
import com.kaver.sso.path.impl.AntPathMatcher;

/**
 * @ClassName: AuthInterceptor
 * @Description: 认证拦截器
 * @author roc
 * @date Aug 11, 2021 2:05:18 PM
 * 
 */
public class AuthInterceptor extends HandlerInterceptorAdapter {

    PathMatcher pathMatcher = new AntPathMatcher();
    @Autowired
    PropertiesConfig propertiesConfig;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return super.preHandle(request, response, handler);
        }
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;
        String servletPath = req.getServletPath();
        if (!StringUtils.isEmpty(propertiesConfig.getSsoAppLogoutPath()) && servletPath.equals(propertiesConfig.getSsoAppLogoutPath())) {
            resp.sendRedirect(propertiesConfig.getSsoServerDomain() + "/logout");
            return false;
        }
        HandlerMethod method = (HandlerMethod)handler;
        // 认证排出校验
        if (!StringUtils.isEmpty(propertiesConfig.getSsoAuthExcludedPaths())) {
            String[] excludePaths = propertiesConfig.getSsoAuthExcludedPaths().split(",");
            if (excludePaths != null && excludePaths.length > 0) {
                for (String excludePath : excludePaths) {
                    if (pathMatcher.match(excludePath.trim(), servletPath)) {
                        return super.preHandle(request, response, handler);
                    }
                }
            }
        }
        UnAuth unAuth = method.getMethodAnnotation(UnAuth.class);
        if (unAuth != null) {
        	return super.preHandle(request, response, handler);
        }
        // 认证校验
        if (SsoUserHolder.get() == null) {
            // 如果是rest接口 返回json 如果是页面 直接重定向到登陆页面
            ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);
            RestController restController = method.getBeanType().getAnnotation(RestController.class);
            if (responseBody != null || restController != null) {
                resp.setContentType("application/json;charset=utf-8");
                resp.getWriter().println(propertiesConfig.getSsoUnloginReturn());
                return false;
            } else {
                String link = req.getRequestURL().toString();
                if (!StringUtils.isEmpty(propertiesConfig.getSsoAppDomain())) {
                    link = propertiesConfig.getSsoAppDomain() + servletPath;
                }
                String loginPage = propertiesConfig.getSsoServerDomain() + "?from=" + link;
                resp.sendRedirect(loginPage);
                return false;
            }
        } else {
            return super.preHandle(request, response, handler);
        }
    }

}
